﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Media;
using Solver.Common;

namespace Solver
{
    /// <summary>
    /// Oblicej oci+usmev = 0 ... to musi platit
    /// </summary>
    public enum face { eye = -1, smile = 1 };
    public enum color { red = 1, green = 2, blue = 3, yellow = 4 };
    
    /// <summary>
    /// Usmev ... s úsměvem jde všechno lépe
    /// </summary>
    public class HalfSmile
    {
        public HalfSmile(short value)
        {
            _value = value;
        }

        ~HalfSmile()
        {
            
        }

        short _value;
        /// <summary>
        /// Hodnoty
        /// </summary>
        public short Value { get { return _value; } }

        /// <summary>
        /// Cast obliceje
        /// </summary>
        public face Face
        {
            get
            {
                if (_value == 0)
                    throw new Exception("Invalid face value=0");

                if (_value < 0)
                    return face.eye;
                else
                    return face.smile;
            }
        }

        // Barva karty - hodnota
        public color Color
        {
            get
            {
                int clr = Math.Abs(_value);
                if (clr < 1 || clr > 4)
                    throw new Exception("bad color value");

                return (color)clr;
            }
        }

        /// <summary>
        /// Vraci vypln karty
        /// </summary>
        public SolidColorBrush Fill
        {
            get
            {
                if (Color == color.green)
                    return new SolidColorBrush(Colors.Green);
                else if (Color == color.blue)
                    return new SolidColorBrush(Colors.Blue);
                else if (Color == color.red)
                    return new SolidColorBrush(Colors.Red);
                else if (Color == color.yellow)
                    return new SolidColorBrush(Colors.Yellow);
                else
                    return new SolidColorBrush(Colors.White);
            }
        }
    }

    /// <summary>
    /// Class describes one card 
    /// </summary>
    public class OneCard : IEquatable<OneCard>, ICloneable
    {
        public OneCard(int id=-1)
        {
            _id = id;
        }
        // kopirovaci kostruktor
        public OneCard(OneCard c)
        {
            _id = c.ID;
            foreach (HalfSmile sm in c.smiles)
            {
                HalfSmile sm_new = new HalfSmile(sm.Value);
                smiles.AddLast(sm_new);
                Update();
            }
        }

        public object Clone()
        {
            return new OneCard(this);
        }

        ~OneCard()
        {
            smiles.Clear();
        }

        // IDecko karty pro identifikaci
        private int _id = -1;
        public int ID { get { return _id; } }

        // kruhove pole ... lze rotovat
        private CircleArray<HalfSmile> smiles = new CircleArray<HalfSmile>();
         
        // precte data ze stringu 
        public void ReadCard(string data)
        {
            string[] values = data.Split(new Char[]{';'});
            if (values.Length != 5)
            {
                throw new IndexOutOfRangeException("incorrect parameter");
            }

            _id = Convert.ToInt16(values[0]);
            short v = Convert.ToInt16(values[1]);
            smiles.AddLast(new HalfSmile(v));
            v = Convert.ToInt16(values[2]);
            smiles.AddLast(new HalfSmile(v));
            v = Convert.ToInt16(values[3]);
            smiles.AddLast(new HalfSmile(v));
            v = Convert.ToInt16(values[4]);
            smiles.AddLast(new HalfSmile(v));
            Update();
        }

        HalfSmile _top;
        public HalfSmile Top { get { return _top; } }
        public HalfSmile GetTop() { return _top; }
        
        HalfSmile _right;
        public HalfSmile Right { get { return _right; } }
        public HalfSmile GetRight() { return _right; }

        HalfSmile _bottom;
        public HalfSmile Bottom { get { return _bottom; } }
        
        public HalfSmile GetBottom()
        { 
            return _bottom; 
        }

        HalfSmile _left;
        public HalfSmile Left { get { return _left; } }
        public HalfSmile GetLeft() { return _left; }

        // Rotace - otaci kartu
        public void Rotate()
        {
            smiles.RotateRight();
            Update();
        }
        // update aktualizuje Top, Left, Right, Bottom
        private void Update()
        {
            int idx = 0;
            foreach (HalfSmile hs in smiles)
            {
                if (idx == 0)
                    _top = hs;
                if (idx == 1)
                    _right = hs;
                if (idx == 2)
                    _bottom = hs;
                if (idx == 3)
                    _left = hs;
                idx++;
            }
        }

        // vyresetuje posuny
        public void Reset()
        {
            smiles.Reset();
            Update();
        }

        // textovy vypis karty
        public override string ToString()
        {
            return Top.Value + ", " + Right.Value + ", " + Bottom.Value + ", " + Left.Value;
        }

        // porovnani dvou karet
        public bool Equals(OneCard other)
        {
            if (this.Top.Value == other.Top.Value && Right.Value == other.Right.Value && Bottom.Value == other.Bottom.Value && Left.Value == other.Left.Value)
            {
                return true;
            }

            return false;
        }
    }
}
